package com.google.common.base;

import org.jetbrains.annotations.Nullable;

public class Preconditions {
    public static void checkState(boolean ret) {
        if (!ret) {
            throw new RuntimeException();
        }
    }

    public static void checkState(boolean ret, String format, Object... args) {
        if (!ret) {
            throw new RuntimeException(String.format(format, args));
        }
    }

    public static void checkPositionIndexes(int start, int end, int size) {
        // Carefully optimized for execution by hotspot (explanatory comment above)
        if (start < 0 || end < start || end > size) {
            throw new IndexOutOfBoundsException(badPositionIndexes(start, end, size));
        }
    }
    public static int checkPositionIndex(int index, int size, @Nullable String desc) {
        // Carefully optimized for execution by hotspot (explanatory comment above)
        if (index < 0 || index > size) {
            throw new IndexOutOfBoundsException(badPositionIndex(index, size, desc));
        }
        return index;
    }

    private static String badPositionIndex(int index, int size, @Nullable String desc) {
        if (index < 0) {
            return Strings.lenientFormat("%s (%s) must not be negative", desc, index);
        } else if (size < 0) {
            throw new IllegalArgumentException("negative size: " + size);
        } else { // index > size
            return Strings.lenientFormat("%s (%s) must not be greater than size (%s)", desc, index, size);
        }
    }
    private static String badPositionIndexes(int start, int end, int size) {
        if (start < 0 || start > size) {
            return badPositionIndex(start, size, "start index");
        }
        if (end < 0 || end > size) {
            return badPositionIndex(end, size, "end index");
        }
        // end < start
        return Strings.lenientFormat("end index (%s) must not be less than start index (%s)", end, start);
    }

    public static void checkArgument(boolean ret) {
        if (!ret) {
            throw new RuntimeException();
        }
    }

    public static void checkArgument(boolean ret, String format, Object... args) {
        if (!ret) {
            throw new RuntimeException(String.format(format, args));
        }
    }

    public static <T> T checkNotNull(T obj) {
        if (obj == null) {
            throw new RuntimeException();
        }
        return obj;
    }

    public static <T> T checkNotNull(T obj, String format, Object... args) {
        if (obj == null) {
            throw new RuntimeException();
        }
        return obj;
    }
}
